<?php
/**
 * GouGuOA 文件管理API控制器
 * 实现现代化RESTful API标准，集成数据权限控制
 */

declare (strict_types=1);

namespace app\controller\home;

use app\BaseController;
use app\common\FileUploadConfig;
use think\facade\Db;
use think\facade\Request;
use think\Request as RequestObject; // 导入Request对象用于依赖注入

class Files extends BaseController
{
    /**
     * 获取文件列表（向后兼容方法）
     */
    public function index()
    {
        return $this->list();
    }
    
    /**
     * 获取文件列表
     * @return \think\Response
     */
    public function list()
    {
        try {
            $param = Request::param();
            $where = [];
            $where[] = ['user_id', '=', $this->getUserId()];
            
            // 按文件名搜索
            if (!empty($param['keywords'])) {
                $where[] = ['name', 'like', '%' . $param['keywords'] . '%'];
            }
            
            // 按文件类型筛选
            if (!empty($param['fileext'])) {
                $where[] = ['fileext', '=', $param['fileext']];
            }
            
            // 按上传时间范围筛选
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['create_time', 'between', [$param['start_time'], $param['end_time']]];
            }
            
            $rows = empty($param['limit']) ? 10 : $param['limit'];
            $list = Db::name('file')
                ->where($where)
                ->order('create_time desc')
                ->paginate(['list_rows' => $rows]);

            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $list->items(),
                'count' => $list->total(),
                'timestamp' => time()
            ]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 获取文件详情
     * @param int $id 文件ID
     * @return \think\Response
     */
    public function read($id)
    {
        try {
            $file = Db::name('file')->where(['id' => $id, 'user_id' => $this->getUserId()])->find();
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在或无权限访问', 'data' => null, 'timestamp' => time()]);
            }

            return json(['code' => 0, 'msg' => '获取成功', 'data' => $file, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 公开获取文件详情（用于合同附件等场景）
     * @param int $id 文件ID
     * @return \think\Response
     */
    public function publicRead($id)
    {
        try {
            $file = Db::name('file')->where(['id' => $id])->find();
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在', 'data' => null, 'timestamp' => time()]);
            }

            return json(['code' => 0, 'msg' => '获取成功', 'data' => $file, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 查看文件详情（兼容旧路由）
     * @param int $id 文件ID
     * @return \think\Response
     */
    public function view($id)
    {
        return $this->read($id);
    }

    /**
     * 上传文件
     * @return \think\Response
     */
    public function save(RequestObject $request)
    {
        if (!$request->isPost()) {
            return json(['code' => 400, 'msg' => '非法请求', 'data' => null, 'timestamp' => time()]);
        }
        
        try {
            $param = $request->param();
            $sourse = 'file';
            if (isset($param['sourse'])) {
                $sourse = $param['sourse'];
            }
            
            // 检查是否有上传文件
            $file = null;
            if ($sourse == 'file' || $sourse == 'tinymce') {
                $file = $request->file('file');
            } else {
                $file = $request->file('editormd-image-file');
            }
            
            // 如果没有找到文件，尝试直接获取第一个上传文件
            if (!$file) {
                $files = $request->file();
                if (!empty($files) && is_array($files)) {
                    $file = reset($files); // 获取第一个文件
                }
            }
            
            // 如果仍然没有文件，返回错误
            if (!$file) {
                return json(['code' => 400, 'msg' => '没有选择上传文件', 'data' => null, 'timestamp' => time()]);
            }
            
            // 验证文件是否有效
            if (!$file->isValid()) {
                return json(['code' => 400, 'msg' => '上传文件无效', 'data' => null, 'timestamp' => time()]);
            }
            
            // 检查临时文件是否存在
            $tempFilePath = $file->getRealPath();
            if (!file_exists($tempFilePath)) {
                return json(['code' => 400, 'msg' => '上传文件临时文件不存在', 'data' => null, 'timestamp' => time()]);
            }
            
            // 获取上传文件的hash散列值
            $sha1 = $file->hash('sha1');
            $md5 = $file->hash('md5');
            
            // 使用全局配置获取允许的文件类型和大小限制
            $fileType = $param['type'] ?? 'all';
            $allowedExtensions = FileUploadConfig::getAllowedExtensions($fileType);
            $maxSize = FileUploadConfig::getMaxSize($fileType);
            
            // 验证文件大小
            $fileSizeBytes = $file->getSize();
            if ($fileSizeBytes === false || $fileSizeBytes > $maxSize) {
                return json(['code' => 400, 'msg' => '文件大小超过限制', 'data' => null, 'timestamp' => time()]);
            }
            
            // 验证文件类型
            $extension = strtolower($file->extension());
            $allowedExtensionsArray = explode(',', $allowedExtensions);
            if (!in_array($extension, $allowedExtensionsArray)) {
                return json(['code' => 400, 'msg' => '不支持的文件类型', 'data' => null, 'timestamp' => time()]);
            }
            
            // 确定模块类型，默认为default
            $module = $param['module'] ?? 'default';
            
            // 生成安全的文件名
            $originalName = $file->getOriginalName();
            $safeFileName = FileUploadConfig::generateSafeFileName($originalName);
            
            // 确保目录存在
            $uploadPath = FileUploadConfig::ensureDirectoryExists($module);
            
            // 移动文件到指定目录
            $filename = $safeFileName;
            $fileFullPath = $uploadPath . DIRECTORY_SEPARATOR . $filename;
            
            // 使用move方法移动文件
            if (!$file->move($uploadPath, $filename)) {
                return json(['code' => 500, 'msg' => '文件移动失败', 'data' => null, 'timestamp' => time()]);
            }
        
            // 写入到附件表
            $data = [];
            $data['filepath'] = FileUploadConfig::getFileUrl($module, $filename);
            $data['name'] = $originalName; // 保存原始文件名
            $data['mimetype'] = $file->getOriginalMime();
            $data['fileext'] = $file->extension();
            $data['filesize'] = $fileSizeBytes;
            $data['filename'] = $filename;
            $data['sha1'] = $sha1;
            $data['md5'] = $md5;
            $data['module'] = 'home';
            $data['action'] = 'files';
            $data['uploadip'] = Request::ip();
            $data['create_time'] = time();
            $data['user_id'] = $this->getUserId();
            $data['status'] = 1;
            $data['admin_id'] = $data['user_id'];
            $data['audit_time'] = time();
            $data['use'] = isset($param['use']) ? $param['use'] : '默认文件'; // 附件用处
            
            $res['id'] = Db::name('file')->insertGetId($data);
            $res['filepath'] = $data['filepath'];
            $res['name'] = $data['name'];
            $res['uid'] = $this->getUserId();
            $res['filename'] = $data['filename'];
            $res['filesize'] = $data['filesize'];
            $res['fileext'] = $data['fileext'];
            
            if ($sourse == 'editormd') {
                // editormd编辑器上传返回
                return json(['success' => 1, 'message' => '上传成功', 'url' => $data['filepath'], 'timestamp' => time()]);
            } else if ($sourse == 'tinymce') {
                // tinymce编辑器上传返回
                return json(['success' => 1, 'message' => '上传成功', 'location' => $data['filepath'], 'timestamp' => time()]);
            } else {
                // 普通上传返回
                return json(['code' => 0, 'msg' => '上传成功', 'data' => $res, 'timestamp' => time()]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '上传失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 上传文件方法（与路由配置匹配）
     * @return \think\Response
     */
    public function upload(RequestObject $request)
    {
        return $this->save($request);
    }

    /**
     * 批量上传文件方法
     * @return \think\Response
     */
    public function uploads(RequestObject $request)
    {
        if (!$request->isPost()) {
            return json(['code' => 400, 'msg' => '非法请求', 'data' => null, 'timestamp' => time()]);
        }
        
        try {
            $param = $request->param();
            $sourse = 'file';
            if (isset($param['sourse'])) {
                $sourse = $param['sourse'];
            }
            
            // 获取上传的文件列表
            $files = $request->file();
            if (empty($files)) {
                return json(['code' => 400, 'msg' => '没有选择上传文件', 'data' => null, 'timestamp' => time()]);
            }
            
            $result = [];
            
            // 处理每个上传的文件
            foreach ($files as $file) {
                // 验证文件是否有效
                if (!$file->isValid()) {
                    continue; // 跳过无效文件
                }
                
                // 检查临时文件是否存在
                $tempFilePath = $file->getRealPath();
                if (!file_exists($tempFilePath)) {
                    continue; // 跳过不存在的临时文件
                }
                
                // 获取上传文件的hash散列值
                $sha1 = $file->hash('sha1');
                $md5 = $file->hash('md5');
                $rule = [
                    'image' => 'jpg,png,jpeg,gif',
                    'doc' => 'txt,doc,docx,ppt,pptx,xls,xlsx,pdf',
                    'file' => 'zip,gz,7z,rar,tar',
                    'video' => 'mpg,mp4,mpeg,avi,wmv,mov,flv,m4v',
                    'audio' => 'mp3,wav,wma,flac,midi',
                ];
                $fileExt = $rule['image'] . ',' . $rule['doc'] . ',' . $rule['file'] . ',' . $rule['video'] . ',' . $rule['audio'];
                
                // 1M=1024*1024=1048576字节
                $file_size = 50; // 默认50M
                if (isset($param['size']) && $param['size']) {
                    $fileSize = $param['size'];
                } else {
                    $fileSize = $file_size * 1024 * 1024;
                }
                
                if (isset($param['type']) && $param['type']) {
                    $fileExt = $rule[$param['type']];
                }
                
                // 验证文件大小
                $fileSizeBytes = $file->getSize();
                if ($fileSizeBytes === false || $fileSizeBytes > $fileSize) {
                    continue; // 跳过超过大小限制的文件
                }
                
                // 验证文件类型
                $extension = strtolower($file->extension());
                $allowedExtensions = explode(',', $fileExt);
                if (!in_array($extension, $allowedExtensions)) {
                    continue; // 跳过不支持的文件类型
                }
                
                // 日期前缀
                $dataPath = date('Ym');
                $use = 'thumb';
                
                // 使用更简洁的文件名生成方式：只包含大小写字母和数字
                $originalName = $file->getOriginalName();
                $nameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
                $ext = pathinfo($originalName, PATHINFO_EXTENSION);
                
                // 生成安全的文件名：只保留大小写字母和数字
                $safeName = preg_replace('/[^a-zA-Z0-9]/', '', $nameWithoutExt);
                // 限制长度
                if (strlen($safeName) > 50) {
                    $safeName = substr($safeName, 0, 50);
                }
                // 确保不为空
                if (empty($safeName)) {
                    $safeName = 'file' . rand(1000, 9999);
                }
                
                // 生成唯一文件名：使用安全的文件名加上随机数字确保唯一性
                $uniqueName = $safeName . rand(1000, 9999);
                // 保证路径分隔符统一使用正斜杠
                $dataPath = str_replace('\\', '/', $dataPath);
                
                // 确保目录存在
                $storagePath = '../public/uploads';
                $fullPath = $storagePath . '/' . $dataPath;
                if (!is_dir($fullPath)) {
                    mkdir($fullPath, 0755, true);
                }
                
                // 移动文件到指定目录
                $filename = $dataPath . '/' . $uniqueName . ($ext ? '.' . $ext : '');
                $fileFullPath = $storagePath . '/' . $filename;
                
                // 使用move方法移动文件
                if (!$file->move($fullPath, $uniqueName . ($ext ? '.' . $ext : ''))) {
                    continue; // 跳过移动失败的文件
                }
            
                // 写入到附件表
                $data = [];
                $data['filepath'] = 'uploads/' . $filename;
                $data['name'] = $originalName; // 保存原始文件名
                $data['mimetype'] = $file->getOriginalMime();
                $data['fileext'] = $file->extension();
                $data['filesize'] = $fileSizeBytes;
                $data['filename'] = $filename;
                $data['sha1'] = $sha1;
                $data['md5'] = $md5;
                $data['module'] = 'home';
                $data['action'] = 'files';
                $data['uploadip'] = $request->ip();
                $data['create_time'] = time();
                $data['user_id'] = $this->getUserId();
                $data['status'] = 1;
                $data['admin_id'] = $data['user_id'];
                $data['audit_time'] = time();
                $data['use'] = isset($param['use']) ? $param['use'] : $use; // 附件用处
                
                $fileId = Db::name('file')->insertGetId($data);
                $data['id'] = $fileId;
                
                $result[] = $data;
            }
            
            return json(['code' => 0, 'msg' => '上传成功', 'data' => $result, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '上传失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 更新文件信息（重命名）
     * @param int $id 文件ID
     * @return \think\Response
     */
    public function update(RequestObject $request)
    {
        try {
            // 检查参数
            $param = $request->param();
            
            // 优先使用URL参数，其次使用请求体参数
            if (empty($id)) {
                $id = isset($param['id']) ? $param['id'] : null;
            }
            
            if (empty($id)) {
                return json(['code' => 400, 'msg' => '文件ID不能为空', 'data' => null, 'timestamp' => time()]);
            }
            
            // 检查文件是否存在
            $file = Db::name('file')->where(['id' => $id, 'user_id' => $this->getUserId()])->find();
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在或无权限访问', 'data' => null, 'timestamp' => time()]);
            }
            
            // 更新文件信息
            $updateData = [];
            if (isset($param['title'])) {
                $updateData['name'] = $param['title'];
            }
            
            if (!empty($updateData)) {
                $updateData['update_time'] = time();
                if (Db::name('file')->where(['id' => $id])->update($updateData) !== false) {
                    return json(['code' => 0, 'msg' => '操作成功', 'data' => null, 'timestamp' => time()]);
                } else {
                    return json(['code' => 500, 'msg' => '操作失败', 'data' => null, 'timestamp' => time()]);
                }
            } else {
                return json(['code' => 400, 'msg' => '没有要更新的数据', 'data' => null, 'timestamp' => time()]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '操作失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 删除文件
     * @param int $id 文件ID
     * @return \think\Response
     */
    public function delete(RequestObject $request)
    {
        try {
            // 检查参数
            $param = $request->param();
            
            // 获取文件ID - 支持多种参数格式，包括RESTful风格
            $id = null;
            
            // 1. 从路由参数获取（RESTful风格：/api/del/341）
            if (isset($param['id'])) {
                $id = $param['id'];
            }
            // 2. 从请求体参数获取（简洁格式：{id: 341}）
            elseif (isset($param['data']['id'])) {
                $id = $param['data']['id'];
            }
            // 3. 从URL查询参数获取（格式：/api/del?id=341）
            elseif (isset($param['ids'])) {
                $id = $param['ids'];
            }
            // 4. 兼容特殊格式：{params: {ids: 341}}
            elseif (isset($param['params']['ids'])) {
                $id = $param['params']['ids'];
            }
            
            // 如果id是数组，取第一个值（兼容批量删除但这里只处理单个）
            if (is_array($id)) {
                $id = $id[0];
            }
            
            if (empty($id)) {
                return json(['code' => 400, 'msg' => '文件ID不能为空', 'data' => null, 'timestamp' => time()]);
            }
            
            // 检查文件是否存在
            $file = Db::name('file')->where('id', $id)->find();
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在', 'data' => null, 'timestamp' => time()]);
            }
            
            // 权限检查：只有超级管理员、文件创建人或相关案件文档创建人可以删除
            $userId = $this->getUserId();
            $userInfo = Db::name('admin')->where('id', $userId)->find();
            $isSuperAdmin = $userInfo && isset($userInfo['menus']) && strpos($userInfo['menus'], '*') !== false;
            
            // 检查是否是文件创建人
            $isFileOwner = $file['user_id'] == $userId;
            
            // 检查是否是相关案件文档的创建人（允许删除文档关联的文件）
            $isDocOwner = false;
            if (!$isFileOwner) {
                $caseDoc = Db::name('case_doc')
                    ->where('file_ids', 'like', '%' . $id . '%')
                    ->where('delete_time', 0)
                    ->find();
                
                if ($caseDoc && $caseDoc['upload_uid'] == $userId) {
                    $isDocOwner = true;
                }
            }
            
            if (!$isSuperAdmin && !$isFileOwner && !$isDocOwner) {
                return json(['code' => 403, 'msg' => '文件不存在或无权限访问', 'data' => null, 'timestamp' => time()]);
            }
            
            // 逻辑删除，只更新delete_time字段（因为数据库表中可能没有update_time字段）
            if (Db::name('file')->where(['id' => $id])->update(['delete_time' => time()]) !== false) {
                return json(['code' => 0, 'msg' => '删除成功', 'data' => null, 'timestamp' => time()]);
            } else {
                return json(['code' => 500, 'msg' => '删除失败', 'data' => null, 'timestamp' => time()]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '删除失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 获取附件分组
     * @return \think\Response
     */
    public function getGroup()
    {
        try {
            // 查询附件分组列表
            $list = Db::name('file_group')
                ->where('status', '>=', 0)
                ->order('id', 'asc')
                ->select()
                ->toArray();
            
            return json(['code' => 0, 'msg' => '获取成功', 'data' => $list, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 新增/编辑附件分组
     * @return \think\Response
     */
    public function addGroup()
    {
        try {
            $param = Request::param();
            
            // 数据验证
            if (empty($param['title'])) {
                return json(['code' => 400, 'msg' => '分组名称不能为空', 'data' => null, 'timestamp' => time()]);
            }
            
            if (!empty($param['id'])) {
                // 编辑分组
                $data = [
                    'id' => $param['id'],
                    'title' => $param['title'],
                    'update_time' => time()
                ];
                
                Db::name('file_group')->update($data);
                return json(['code' => 0, 'msg' => '编辑成功', 'data' => null, 'timestamp' => time()]);
            } else {
                // 新增分组
                $data = [
                    'title' => $param['title'],
                    'status' => 1,
                    'create_time' => time(),
                    'update_time' => time()
                ];
                
                $groupId = Db::name('file_group')->insertGetId($data);
                return json(['code' => 0, 'msg' => '新增成功', 'data' => ['id' => $groupId], 'timestamp' => time()]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '操作失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 删除附件分组
     * @return \think\Response
     */
    public function delGroup()
    {
        try {
            $param = Request::param();
            
            if (empty($param['id'])) {
                return json(['code' => 400, 'msg' => '参数错误', 'data' => null, 'timestamp' => time()]);
            }
            
            // 检查分组是否存在
            $group = Db::name('file_group')->where('id', $param['id'])->find();
            if (empty($group)) {
                return json(['code' => 404, 'msg' => '分组不存在', 'data' => null, 'timestamp' => time()]);
            }
            
            // 检查分组下是否有文件
            $fileCount = Db::name('file')->where('group_id', $param['id'])->count();
            if ($fileCount > 0) {
                return json(['code' => 400, 'msg' => '该分组下还有文件，无法删除', 'data' => null, 'timestamp' => time()]);
            }
            
            // 删除分组
            Db::name('file_group')->where('id', $param['id'])->delete();
            
            return json(['code' => 0, 'msg' => '删除成功', 'data' => null, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '删除失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }

    /**
     * 移动文件
     * @return \think\Response
     */
    public function move()
    {
        try {
            $param = Request::param();
            
            if (empty($param['ids']) || empty($param['group_id'])) {
                return json(['code' => 400, 'msg' => '参数错误', 'data' => null, 'timestamp' => time()]);
            }
            
            $ids = is_array($param['ids']) ? $param['ids'] : explode(',', $param['ids']);
            
            // 检查文件是否存在且有权限
            $files = Db::name('file')->where('id', 'in', $ids)->select();
            foreach ($files as $file) {
                if ($file['user_id'] != $this->getUserId()) {
                    return json(['code' => 403, 'msg' => '无权限操作文件', 'data' => null, 'timestamp' => time()]);
                }
            }
            
            // 更新文件分组
            Db::name('file')->where('id', 'in', $ids)->update([
                'group_id' => $param['group_id'],
                'update_time' => time()
            ]);
            
            return json(['code' => 0, 'msg' => '移动成功', 'data' => null, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '移动失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 下载文件
     * @return \think\Response
     */
    public function download()
    {
        try {
            // 接收参数
            $param = Request::param();
            $id = isset($param['id']) ? intval($param['id']) : 0;
            
            if (empty($id)) {
                return json(['code' => 400, 'msg' => '文件ID不能为空', 'data' => null, 'timestamp' => time()]);
            }
            
            // 首先查询文件基本信息，但不立即检查所有权
            $file = Db::name('file')->where('id', '=', $id)->find();
            
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在或无权限访问', 'data' => null, 'timestamp' => time()]);
            }
            
            // 获取当前用户ID
            $userId = $this->getUserId();
            
            // 检查文件访问权限
            $hasAccess = false;
            
            // 1. 如果用户是文件所有者，则有权限
            if ($file['user_id'] == $userId) {
                $hasAccess = true;
            }
            // 2. 如果文件关联到笔记，允许所有登录用户下载
            else if ($file['module'] == 'article' && !empty($file['group_id'])) {
                // 知识笔记附件允许所有登录用户下载
                $hasAccess = true;
            }
            
            if (!$hasAccess) {
                return json(['code' => 404, 'msg' => '文件不存在或无权限访问', 'data' => null, 'timestamp' => time()]);
            }
            
            // 使用全局配置获取文件下载路径，兼容新旧文件路径
            $filePath = FileUploadConfig::getDownloadPath($file);
            
            if (!$filePath) {
                return json(['code' => 404, 'msg' => '文件不存在或已被删除', 'data' => null, 'timestamp' => time()]);
            }
            
            // 增加下载次数
            Db::name('file')->where(['id' => $id])->inc('download', 1)->update();
            
            // 返回文件下载响应
            return download($filePath, $file['name']);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '下载失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 批量下载文件
     * @return \think\Response
     */
    public function batchDownload()
    {
        try {
            // 接收参数
            $param = Request::param();
            $ids = isset($param['ids']) ? $param['ids'] : [];
            
            if (empty($ids)) {
                return json(['code' => 400, 'msg' => '请选择要下载的文件', 'data' => null, 'timestamp' => time()]);
            }
            
            // 将ids转换为数组
            if (!is_array($ids)) {
                $ids = explode(',', $ids);
            }
            
            // 获取当前用户ID
            $userId = $this->getUserId();
            
            // 查询文件基本信息
            $fileList = Db::name('file')
                ->whereIn('id', $ids)
                ->select();
            
            if (empty($fileList)) {
                return json(['code' => 404, 'msg' => '未找到可下载的文件', 'data' => null, 'timestamp' => time()]);
            }
            
            // 过滤用户有权限下载的文件
            $files = [];
            foreach ($fileList as $file) {
                $hasAccess = false;
                
                // 1. 如果用户是文件所有者，则有权限
                if ($file['user_id'] == $userId) {
                    $hasAccess = true;
                }
                // 2. 如果文件关联到笔记，允许所有登录用户下载
                else if ($file['module'] == 'article' && !empty($file['group_id'])) {
                    // 知识笔记附件允许所有登录用户下载
                    $hasAccess = true;
                }
                
                if ($hasAccess) {
                    $files[] = $file;
                }
            }
            
            if (empty($files)) {
                return json(['code' => 404, 'msg' => '未找到可下载的文件', 'data' => null, 'timestamp' => time()]);
            }
            
            // 提取有权限下载的文件ID数组
            $accessibleFileIds = array_column($files, 'id');
            
            // 增加下载次数
            Db::name('file')
                ->whereIn('id', $accessibleFileIds)
                ->inc('download', 1)
                ->update();
            
            // 如果只有一个文件，直接下载
            if (count($files) === 1) {
                $file = $files[0];
                // 使用全局配置获取文件下载路径，兼容新旧文件路径
                $filePath = FileUploadConfig::getDownloadPath($file);
                if (!$filePath) {
                    return json(['code' => 404, 'msg' => '文件不存在或已被删除', 'data' => null, 'timestamp' => time()]);
                }
                return download($filePath, $file['name']);
            }
            
            // 多个文件打包下载（这里简化处理，实际项目中可能需要更复杂的打包逻辑）
            return json(['code' => 200, 'msg' => '暂不支持批量下载', 'data' => null, 'timestamp' => time()]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '批量下载失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 向后兼容方法：编辑文件
     */
    public function edit(RequestObject $request)
    {
        return $this->update($request);
    }
    
    /**
     * 向后兼容方法：添加文件
     */
    public function add(RequestObject $request)
    {
        return $this->save($request);
    }
    
    /**
     * 向后兼容方法：删除文件
     */
    public function del(RequestObject $request)
    {
        return $this->delete($request);
    }
}